package aufgabe01;

import java.io.*;
import java.util.*;

public class TestClassCalculator
{
  public static void main(String[] args)
  {
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    HashMap<String, Double> map = new HashMap<String, Double>();
    
    String s = "";
    System.out.println("enter 'q' to quit");
    try
    {
      while(true)
      {
        s = in.readLine();
        if(s.equals("q"))
          break;
        System.out.println("task '"+s+"' => "+analyze(s, map));
      }
    } catch (IOException e)
    {
    }
  }
  
  public static String analyze(String expr, HashMap<String, Double> mapVars)
  {
    if(expr.contains("="))
    {
      String varName = expr.substring(0, expr.indexOf("=")-1);
      double value = eval(expr.substring(expr.indexOf("=")+2), mapVars);
      mapVars.put(varName, value);
      return "variable '"+varName+"' defined, value = "+value;
    }
    else
    {
      return "result = "+eval(expr, mapVars);
    }
  }
  
  public static double eval(String exprUPN, HashMap<String, Double> mapVars)
  {
    String[] elements = exprUPN.split(" ");
    Stack<Double> stack = new Stack<Double>();
    for(String element : elements)
    {
      try
      {
        // Ist das Element eine Zahl?
        double value = Double.parseDouble(element);
        // Wenn ja: Auf Stack legen
        stack.add(value);
      }
      catch (Exception e)
      {
        // Wenn nicht: Ist das Element eine Variable?
        if(mapVars.containsKey(element))
          // Wenn ja: Wert der Variable auf Stack legen
          stack.add(mapVars.get(element));
        else
        {
          // Wenn das Element keine Variable ist,
          // ist es ein Operator, also letzen beiden Stack-Elemente verrechnen
          if(stack.size()<2)
            return Math.acos(2);
          double value2 = stack.pop();
          double value1 = stack.pop();
          if(element.equals("+"))
            stack.add(value1+value2);
          else if(element.equals("-"))
            stack.add(value1-value2);
          else if(element.equals("*"))
            stack.add(value1*value2);
          else if(element.equals("/"))
            stack.add(value1/value2);
        }
      }
    }
    if(stack.size()>1)
      return Math.acos(2);
    return stack.pop();
  }
}
